// 定义类
class Person {
    //// 定义属性
    // 标准定义
    age: number
    // 带初始化的类型定义
    gender: string = 'male'

    //// 构造函数
    constructor(age: number, gender: string) {
        this.age = age
        this.gender = gender
    }

    //// 实例方法
    // 标准定义法
    scale1(n: number): void {
        this.age *= n
        console.log(this.age)
    }
    // 箭头定义法
    scale2 = (n: number): void => {
        this.age *= n
        console.log(this.age)
    }

    //// 静态方法
    static testStatic(age: number ,n: number): void {
        console.log(n*age)
    }
}


// // 定义实例对象
// const person21 = new Person(19 , 'black')
// // 使用类
// Person.testStatic(19, 3)
// // 使用对象
// person21.scale1(3)
// person21.scale2(3)
// console.log(person21.age)
// console.log(typeof p);

///////////////// 继承 /////////////////
class Father extends Person {
    scaleSon = (n: number): void => {
        this.age *= n
        console.log(this.age)
    }
}
// let father = new Father(19 , 'black')
// father.scale1(3)
// father.scaleSon(3)

///////////////// 多态 /////////////////
// 定义接口类
interface PersonFace {
    age: number,
    gender: string,
    scale1: (age: number, gender: string) => void
    scale2(age: number, gender: string): void
}
// 使用接口类
class Mother extends Person implements PersonFace {
    name: string = "na"
}
// class Mother implements PersonFace {
//     age: number
//     gender: string = 'male'
//     constructor(age: number, gender: string) {
//         this.age = age
//         this.gender = gender
//     }
//     scale1(n: number): void {
//         this.age *= n
//         console.log(this.age)
//     }
    
// }
// 类的属性和方法相对接口类可以多但不能少
let mother = new Mother(55, 'female')
// mother.scale1(3)

///////////////// 封装 /////////////////
// public修饰符
class Animal {
    // 属性
    public age: number
    protected gender: string = 'male'
    private name: string
    readonly isMine: boolean

    // 构造函数
    constructor(age: number, gender: string, name: string, isMine: boolean) {
        this.age = age
        this.gender = gender
        this.name = name
        this.isMine = isMine
    }

    // 实例方法
    public scale1(n: number): void {
        this.age *= n
        console.log(this.age)
    }
    protected scale2 = (n: number): void => {
        this.age *= n
        console.log(this.age)
    }
    private scale3 = (n: number): void => {
        this.age *= n
        console.log(this.age)
    }

     // public 可见
     logAge(): void {
        console.log(this.age)
    }
    // protected 可见
    logGender(): void {
        console.log(this.gender)
    }

    // private 可见
    logName(): void {
        console.log(this.name)
    }
    // readonly 可见不可改
    logIsMine(): void {
        console.log(this.isMine)
    }
    // changeMine(): void {
    //     this.isMine = !this.isMine
    // }

}

class Dog extends Animal {
    // public 可见
    logAge(): void {
        console.log(this.age)
    }
    // protected 可见
    logGender(): void {
        console.log(this.gender)
    }

    // private 不可见
    // logName(): void {
    //     console.log(this.name)
    // }
    // readonly 可见不可改
    logIsMine(): void {
        console.log(this.isMine)
    }
    // changeMine(): void {
    //     this.isMine = !this.isMine
    // }
}

let animal = new Animal(10 , 'male' , 'black', false)
// public 可见
console.log(animal.age)
//// protected 不可见
// console.log(animal.name)
//// private 不可见
// console.log(animal.gender)
//// readonly 可见不可改
console.log(animal.isMine)
// animal.isMine = true
let dog = new Dog(10 , 'male' , 'black', true)
// public 可见
console.log(dog.age)
//// protected 不可见
// console.log(dog.name)
//// private 不可见
// console.log(dog.gender)
//// readonly 可见不可改
console.log(dog.isMine)
// animal.isMine = false


interface IAnimal {
    readonly isMine: boolean
}